home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / DI.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-20  |  7.6 KB  |  267 lines

  1. /*
  2.  * DI.h -  support for invariants (assertions) using the gdb debugger.
  3.  *
  4.  * Copyright (c) 1997 Phil Maker
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26.  * SUCH DAMAGE.
  27.  *
  28.  * Id: DI.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp 
  29.  */
  30.  
  31. #ifndef _DI_h_
  32. #define _DI_h_ 1
  33.  
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37.  
  38. #ifndef WITHOUT_NANA 
  39.  
  40. /*
  41.  * nana-config.h - the system wide configuration file; we put the ifndef
  42.  *   around it to avoid the file 5 million times during a compile.
  43.  */
  44.  
  45. #ifndef _nana_config_h_
  46. #include <nana-config.h>
  47. #endif
  48.  
  49. /* 
  50.  * DI_LEVEL sets the level of invariant analogously to NDEBUG in assert.h
  51.  *
  52.  *   DI_LEVEL == 2: invariants are always evaluated.
  53.  *   DI_LEVEL == 1: evaluate invariants iff they have a true GUARD.
  54.  *   DI_LEVEL == 0: invariants are never evaluated.
  55.  */
  56.  
  57. #ifndef DI_LEVEL /* define DEFAULT for DI_LEVEL */
  58. #define DI_LEVEL 1
  59. #endif
  60.  
  61.  
  62.  
  63. /*
  64.  * DI_DEFAULT_GUARD - the default guard expression; an invariant is checked
  65.  *     iff the guard is true. By default its always true.
  66.  */
  67.  
  68. #ifndef DI_DEFAULT_GUARD
  69. #define DI_DEFAULT_GUARD 1
  70. #endif
  71.  
  72. /*
  73.  * DI_DEFAULT_PARAMS - the default value to be passed as the second argument
  74.  *       to the handler macro when an invariant fails.
  75.  */
  76.  
  77. #ifndef DI_DEFAULT_PARAMS
  78. #define DI_DEFAULT_PARAMS /* nothing */
  79. #endif
  80.  
  81. /*
  82.  * DI_DEFAULT_HANDLER - called when an error is detected by DI; 
  83.  */
  84.  
  85. #ifndef DI_DEFAULT_HANDLER /* define default handler */
  86.  
  87. #define DI_DEFAULT_HANDLER(e,f,l,p) \
  88.   @@echo e has failed at f:l with p\n@@ \
  89.   @@where@@ /* stack backtrace */
  90.  
  91. #endif /* DI_DEFAULT_HANDLER */
  92.  
  93. /*
  94.  * DI_MAKE_VALID_BREAKPOINT(e) - called whenever we generate a DI breakpoint;
  95.  *     the aim is to make sure a breakpoint can be set at the current location
  96.  *     and that any expressions will be evaluated by gdb correctly. 
  97.  *     This is the portable default; an architecture specific version
  98.  *     is generated by the configure script into nana-config.h
  99.  */
  100.  
  101. #ifndef DI_MAKE_VALID_BREAKPOINT
  102. static volatile int _di_target;
  103.  
  104. #define DI_MAKE_VALID_BREAKPOINT(e) _di_target = 0
  105. #endif
  106.  
  107. /*
  108.  * _DIGHPS - implements the DI macros, it comes in two variants:
  109.  * 
  110.  * ifdefined(_NANA_FILTER_) then we are generating debugger commands
  111.  * else generating C text.
  112.  */
  113.  
  114. #if DI_LEVEL == 2 /* always check the assertion */
  115. #ifdef _NANA_FILTER_
  116. #define _DIGHPS(e,g,h,p,s) \
  117.     @@break @__FILE__:__LINE__@@ \
  118.     @@condition $bpnum (!(e))@@ \
  119.     @@command $bpnum@@ \
  120.     @@silent@@ \
  121.         h(s,f,l,p) \
  122.     @@end@@
  123. #else
  124. #define _DIGHPS(e,g,h,p,s) DI_MAKE_VALID_BREAKPOINT(e)
  125. #endif /* _NANA_FILTER_ */
  126.  
  127. #elif DI_LEVEL == 1 /* check it iff g is true */
  128.  
  129. #ifdef _NANA_FILTER_
  130. #define _DIGHPS(e,g,h,p,s) \
  131.     @@break @__FILE__:__LINE__@@ \
  132.     @@condition $bpnum (g) && (!(e))@@ \
  133.     @@command $bpnum@@ \
  134.     @@silent@@ \
  135.         h(s,f,l,p) \
  136.     @@end@@
  137. #else 
  138. #define _DIGHPS(e,g,h,p,s) DI_MAKE_VALID_BREAKPOINT(e)
  139. #endif /* _NANA_FILTER_ */
  140.  
  141. #elif DI_LEVEL == 0 /* no assertions so just remove them */
  142. #define _DIGHPS(e,g,h,p,s) /* nothing */
  143. #endif /* DI_LEVEL */
  144.  
  145.  
  146. /*
  147.  * DSG(e,g), DS(e) - are used to set variables in the debugger from 
  148.  *        within C programs. These convenience variables can then be
  149.  *        used in invariants later on to refer to the previous state 
  150.  *        of the program.
  151.  * 
  152.  *        DS($x = x); ....; DI($x + 10 == x); 
  153.  */
  154.  
  155. #if DI_LEVEL == 2
  156. #ifdef _NANA_FILTER_
  157. #define DSG(e,g) \
  158.     @@break @__FILE__:__LINE__@@ \
  159.     @@command@@ \
  160.     @@silent@@ \
  161.     @@set e@@ \
  162.     @@cont@@ \
  163.     @@end@@
  164. #else 
  165. #define DSG(e,g) DI_MAKE_VALID_BREAKPOINT(e)
  166. #endif
  167.  
  168. #elif DI_LEVEL == 1
  169. #ifdef _NANA_FILTER_
  170. #define DSG(e,g) \
  171.     @@break @__FILE__:__LINE__ if g@@ \
  172.     @@command@@ \
  173.     @@silent@@ \
  174.     @@set e@@ \
  175.     @@cont@@ \
  176.     @@end@@
  177. #else
  178. #define DSG(e,g) DI_MAKE_VALID_BREAKPOINT(e)
  179. #endif /* _NANA_FILTER_ */
  180.  
  181. #elif DI_LEVEL == 0
  182. #define DSG(e,g) /* nothing */
  183. #else
  184. error DI_LEVEL should be 0 or 1 or 2
  185. #endif
  186.  
  187. #define DS(e) DSG(e,DI_DEFAULT_GUARD)
  188.  
  189. /*
  190.  * And all the user macros; these are used to put in the default arguments.
  191.  * The name is used to determine the arguments; e.g. DIGH takes an expression
  192.  * to check; a guard and a handler as parameters. The letters in the names
  193.  * are in ascending order (i.e. DIGH(...) not DIHG(...)).
  194.  *
  195.  * DI[G][H][P] - it must be true (e) with an optional guard, handler and 
  196.  *    parameter for the handler.
  197.  * DN[G][H][P] - as for DI... except that (e) must never ever be true.
  198.  */
  199.  
  200. #define DI(e) \
  201.   _DIGHPS(e,DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DI("#e")")
  202. #define DIG(e,g) \
  203.   _DIGHPS(e,g,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DI("#e")")
  204. #define DIH(e,h) \
  205.   _DIGHPS(e,DI_DEFAULT_GUARD,h,DI_DEFAULT_PARAMS,"DI("#e")")
  206. #define DIP(e,p) \
  207.   _DIGHPS(e,DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,p,"DI("#e")")
  208. #define DIGH(e,g,h) \
  209.   _DIGHPS(e,g,h,DI_DEFAULT_PARAMS,"DI("#e")")
  210. #define DIGP(e,g,p) \
  211.   _DIGHPS(e,g,DI_DEFAULT_HANDLER,p,"DI("#e")")
  212. #define DIHP(e,h,p) \
  213.   _DIGHPS(e,DI_DEFAULT_GUARD,h,p,"DI("#e")")
  214. #define DIGHP(e,g,h,p) \
  215.   _DIGHPS(e,g,h,p,"DI("#e")")
  216.  
  217. #define DN(e) \
  218.   _DIGHPS((!(e)),DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DN("#e")")
  219. #define DNG(e,g) \
  220.   _DIGHPS((!(e)),g,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DN("#e")")
  221. #define DNH(e,h) \
  222.   _DIGHPS((!(e)),DI_DEFAULT_GUARD,h,DI_DEFAULT_PARAMS,"DN("#e")")
  223. #define DNP(e,p) \
  224.   _DIGHPS((!(e)),DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,p,"DN("#e")")
  225. #define DNGH(e,g,h) \
  226.   _DIGHPS((!(e)),g,h,DI_DEFAULT_PARAMS,"DN("#e")")
  227. #define DNGP(e,g,p) \
  228.   _DIGHPS((!(e)),g,DI_DEFAULT_HANDLER,p,"DN("#e")")
  229. #define DNHP(e,h,p) \
  230.   _DIGHPS((!(e)),DI_DEFAULT_GUARD,h,p,"DN("#e")")
  231. #define DNGHP(e,g,h,p) \
  232.   _DIGHPS((!(e)),g,h,p,"DN("#e")")
  233.  
  234. #else /* defined(WITHOUT_NANA) */
  235.  
  236. #define DI(e) /* empty */
  237. #define DIG(e,g) /* empty */
  238. #define DIH(e,h) /* empty */
  239. #define DIP(e,p) /* empty */
  240. #define DIGH(e,g,h) /* empty */
  241. #define DIGP(e,g,p) /* empty */
  242. #define DIHP(e,h,p) /* empty */
  243. #define DIGHP(e,g,h,p) /* empty */
  244.  
  245. #define DN(e) /* empty */
  246. #define DNG(e,g) /* empty */
  247. #define DNH(e,h) /* empty */
  248. #define DNP(e,p) /* empty */
  249. #define DNGH(e,g,h) /* empty */
  250. #define DNGP(e,g,p) /* empty */
  251. #define DNHP(e,h,p) /* empty */
  252. #define DNGHP(e,g,h,p) /* empty */
  253.  
  254. #define DS(e) /* empty */
  255. #define DSG(e,g) /* empty */
  256.  
  257.  
  258. #endif /* !defined(WITHOUT_NANA) */
  259. #ifdef __cplusplus
  260. }
  261. #endif
  262.  
  263. #endif /* _DI_h_ */
  264.  
  265.  
  266.  
  267.